/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package model.creature.monster;

import java.awt.Image;
import java.util.ArrayList;
import model.creature.Creature;
import model.creature.DamageableCreature;
import model.creature.moving_creature.ActionType;
import model.creature.moving_creature.Direction;
import model.game.GameInterface;
import model.map.cell.Cell;

/**
 * Monster that can do ranged attacks
 */
public abstract class DefaultHealerMonster extends DefaultMonster {

  protected int next_move_;

  /**
   * Constructor
   * @param game - owner
   * @param cell - initial location
   */
  public DefaultHealerMonster(GameInterface game, Cell cell) {
    super(game, cell);
    next_move_ = 0;
  }

  @Override
  public void advanceTime() {

    --next_move_;
    if (next_move_ > 0) return;
    next_move_ = getSpeed();

    ArrayList<DamageableCreature> crts = game_.getCreatures().getAllDamageableCreatures();
    int maxcnt = getHealCount();
    for (DamageableCreature crt : crts) {
      if (maxcnt <= 0) break;
      Creature crtcrt = (Creature)crt;
      if (canHeal(crt) &&
              Math.abs(crtcrt.getCell().getX() - this.getCell().getX()) +
              Math.abs(crtcrt.getCell().getY() - getCell().getY()) <=
              healDistance()) {
        --maxcnt;
        crt.heal(this.getHealValue());
        game_.addMessage(this.getName() + " heals " + crtcrt.getName() +
                " by " + this.getHealValue());
      }
    }

    if (maxcnt == getHealCount()) performSingleAction();
  }

  @Override
  protected ActionType getActionType(Cell cell, Direction dir) {
    return ActionType.kActionStay;
  }

  @Override
  protected int howImportantIsFacingThis(model.map.cell.Cell cell) {
    return 0;
  }

  @Override
  protected int howImportantIsBeingHere(Cell cell, Direction dir) {
    ArrayList<DamageableCreature> crts = game_.getCreatures().getAllDamageableCreatures();
    int maxcnt = getHealCount();
    for (DamageableCreature crt : crts) {
      if (maxcnt <= 0) break;
      Creature crtcrt = (Creature)crt;
      if (canHeal(crt) &&
              Math.abs(crtcrt.getCell().getX() - cell.getX()) +
              Math.abs(crtcrt.getCell().getY() - cell.getY()) <=
              healDistance()) {
        return 1;
      }
    }
    return 0;
  }

  @Override
  public void advanceDay() {

  }

  /**
   * Gets maximum HP of monster at current level.
   *
   * To obtain the level, use getLevel(). Level starts at 0
   */
  @Override
  public abstract int getMaxHP();

  /**
   * Retrieves the name of this monster. Primary Key.
   */
  @Override
  public abstract String getName();

    /**
   * Retrieves the description of this monster
   */
  @Override
  public abstract String getDescription();

  /**
   * Return true if monster can be stepped on and step on unsteppable locations
   */
  @Override
  public abstract boolean isSteppable();

  /**
   * Can this creature steps on unsteppable cells?
   */
  @Override
  public abstract boolean canStepOnUnsteppableCells();

  /**
   * Return true if
   */
  @Override
  public abstract Image getImage();

  /**
   * Determines the damage done by a creature when attacking
   */
  @Override
  public abstract int getPower();

  /**
   * Get the speed of this monster
   *
   * This is the number of turns the monster must wait before attacking again.
   * 1 is the fastest (acts every turn), 2 acts every other turn, etc.
   */
  public abstract int getSpeed();

  /**
   * Retrieves attack distance
   */
  public abstract int healDistance();

  /**
   * Retrieves heal count (monsters healed at a time)
   */
  public abstract int getHealCount();

  /**
   * Do this monster WANT TO heal crt?
   */
  public abstract boolean canHeal(DamageableCreature crt);

  /**
   * How much can this monster heal?
   */
  public abstract int getHealValue();
}
